using System;
using System.Collections.Generic;
using System.Text;
using Zsa.Emulation.Util;

namespace Zsa.Emulation.Render
{
    /// <summary>
    /// Base class for all device settings.
    /// </summary>
    public abstract class RenderDeviceSettings < TCaps, TDeviceSettings, TRenderBase >: ICloneable,
        IEquatable<TDeviceSettings>
        where TCaps : RenderDeviceCapabilities<TCaps, TDeviceSettings, TRenderBase>
        where TRenderBase : RenderDevice<TCaps, TDeviceSettings, TRenderBase>
        where TDeviceSettings : RenderDeviceSettings<TCaps, TDeviceSettings, TRenderBase>
    {

        #region Fields
        /// <summary>
        /// The render device item.
        /// </summary>
        private readonly RenderDeviceItem _Item;
        #endregion Fields

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="T:RenderDeviceSettings"/> class.
        /// </summary>
        /// <param name="deviceItem">The device item.</param>
        /// <param name="deviceType">Type of the device.</param>
        protected internal RenderDeviceSettings(RenderDeviceItem deviceItem, 
            RenderDeviceType deviceType)
        {
            if (deviceType != deviceItem.RenderType)
            {
                throw new ArgumentException();
            }
            _Item = deviceItem;
        }
        #endregion Constructor

        #region Methods

        /// <summary>
        /// Creates the device.
        /// </summary>
        /// <returns></returns>
        public abstract TRenderBase CreateDevice();

        /// <summary>
        /// Checks to see if the settings are valid.
        /// </summary>
        /// <returns></returns>
        public abstract bool IsValid();

        /// <summary>
        /// Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <param name="other">An object to compare with this object.</param>
        /// <returns>
        /// true if the current object is equal to the other parameter; otherwise, false.
        /// </returns>
        public abstract bool Equals(TDeviceSettings other);

        /// <summary>
        /// Clones this instance.
        /// </summary>
        /// <returns></returns>
        public virtual TDeviceSettings Clone()
        {
            return SerializationHelper.Clone(this) as TDeviceSettings;
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        object ICloneable.Clone()
        {
            return this.Clone();
        }
        #endregion Methods

        #region Properties

        /// <summary>
        /// Gets the name of the device.
        /// </summary>
        /// <value>The name of the device.</value>
        public string DeviceName
        {
            get
            {
                return _Item.Name;
            }
        }

        /// <summary>
        /// Gets the device id.
        /// </summary>
        /// <value>The device id.</value>
        public object DeviceId
        {
            get
            {
                return _Item.Id;
            }
        }
        /// <summary>
        /// Gets the type of the device.
        /// </summary>
        /// <value>The type of the device.</value>
        public RenderDeviceType RenderDeviceType
        {
            get
            {
                return _Item.RenderType;
            }
        }

        /// <summary>
        /// Gets the device item.
        /// </summary>
        /// <value>The device item.</value>
        public RenderDeviceItem DeviceItem
        {
            get
            {
                return _Item;
            }
        }

        /// <summary>
        /// The capabilties of the renderer
        /// </summary>
        public abstract TCaps Capabilities { get; }
        #endregion Properties

    }
}
